import 'package:flutter/material.dart';

class KeyGame extends StatefulWidget {
  const KeyGame({Key? key}) : super(key: key);

  @override
  _KeyGameState createState() => _KeyGameState();
}

class _KeyGameState extends State<KeyGame> {
  List<Color> colors = [
    Colors.blue[100]!,
    Colors.blue[300]!,
    Colors.blue[500]!,
    Colors.blue[700]!,
    Colors.blue[900]!,
  ];
  double x = 100;
  double y = 60;
  double _offset = 0;
  GlobalKey _globalKey = GlobalKey();
  late int _slot;

  _shuffle() {
    setState(() {
      colors.shuffle();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('key game')),
      body: Listener(
        onPointerMove: (event) {
          double dy = event.position.dy - _offset;
          if (dy < _slot * y) {
            if (_slot == 0) return;
            setState(() {
              colors.insert(_slot - 1, colors.removeAt(_slot));
              _slot--;
            });
          } else if (dy > (_slot + 1) * y) {
            if (_slot == colors.length - 1) return;
            setState(() {
              colors.insert(_slot, colors.removeAt(_slot + 1));
              _slot++;
            });
          }
        },
        child: Stack(
            key: _globalKey,
            children: colors.map((e) {
              int i = colors.indexOf(e);
              return Box(
                color: e,
                x: x,
                y: i * y,
                key: ValueKey(e),
                onDragPressed: (color) {
                  _slot = colors.indexOf(color);
                  final renderbox = (_globalKey.currentContext!
                      .findRenderObject() as RenderBox);
                  _offset = renderbox.localToGlobal(Offset.zero).dy;
                },
              );
            }).toList()),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _shuffle,
        child: const Icon(Icons.refresh),
      ),
    );
  }
}

class Box extends StatefulWidget {
  const Box(
      {required this.color,
      required this.x,
      required this.y,
      required this.onDragPressed,
      Key? key})
      : super(key: key);
  final Color color;
  final double x;
  final double y;
  final void Function(Color) onDragPressed;

  @override
  _BoxState createState() => _BoxState();
}

class _BoxState extends State<Box> {
  @override
  Widget build(BuildContext context) {
    return AnimatedPositioned(
      duration: Duration(milliseconds: 100),
      left: widget.x,
      top: widget.y,
      child: Draggable(
        onDragStarted: () => widget.onDragPressed(widget.color),
        feedback: Container(
          width: 50,
          height: 50,
          margin: const EdgeInsets.all(10),
          color: widget.color,
        ),
        childWhenDragging: Container(
          width: 50,
          height: 50,
          margin: const EdgeInsets.all(10),
        ),
        child: Container(
          width: 50,
          height: 50,
          margin: const EdgeInsets.all(10),
          color: widget.color,
        ),
      ),
    );
  }
}
